package com.hanxiaozhang.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

/**
 * 〈一句话功能简述〉<br>
 * 〈资源工具类〉
 *
 * @author hanxinghua
 * @create 2022/4/25
 * @since 1.0.0
 */
public class ResourceUtil {

    //---- Jar包的读取方式 ----

    public static InputStream getInputStream(String path) throws IOException {
        InputStream is;
        path = StringUtil.cleanPath(path);
        ClassLoader classLoader = getDefaultClassLoader();
        if (classLoader != null) {
            is = classLoader.getResourceAsStream(path);
        } else {
            is = ClassLoader.getSystemResourceAsStream(path);
        }
        if (is == null) {
            throw new FileNotFoundException(getDescription(path) + " cannot be opened because it does not exist");
        } else {
            return is;
        }
    }

    private static String getDescription(String path) {
        StringBuilder builder = new StringBuilder("class path resource [");
        String pathToUse = path;
        if (pathToUse.startsWith("/")) {
            pathToUse = pathToUse.substring(1);
        }
        builder.append(pathToUse);
        builder.append(']');
        return builder.toString();
    }

    //---- War包的读取方式 ----

    public static File getFile(String path) throws FileNotFoundException {
        String description = "class path resource [" + path + "]";
        ClassLoader cl = getDefaultClassLoader();
        URL url = cl != null ? cl.getResource(path) : ClassLoader.getSystemResource(path);
        if (url == null) {
            throw new FileNotFoundException(description + " cannot be resolved to absolute file path because it does not exist");
        } else {
            return getFile(url, description);
        }
    }

    public static File getFile(URL resourceUrl, String description) throws FileNotFoundException {
        if (!"file".equals(resourceUrl.getProtocol())) {
            throw new FileNotFoundException(description + " cannot be resolved to absolute file path because it does not reside in the file system: " + resourceUrl);
        } else {
            try {
                return new File(toURI(resourceUrl).getSchemeSpecificPart());
            } catch (URISyntaxException var3) {
                return new File(resourceUrl.getFile());
            }
        }
    }

    public static URI toURI(URL url) throws URISyntaxException {
        return toURI(url.toString());
    }

    public static URI toURI(String location) throws URISyntaxException {
        return new URI(StringUtil.replace(location, " ", "%20"));
    }

    private static ClassLoader getDefaultClassLoader() {
        ClassLoader cl = null;
        try {
            cl = Thread.currentThread().getContextClassLoader();
        } catch (Throwable ex) {
            // Cannot access thread context ClassLoader - falling back...
        }
        if (cl == null) {
            // No thread context class loader -> use class loader of this class.
            cl = ResourceUtil.class.getClassLoader();
            if (cl == null) {
                // getClassLoader() returning null indicates the bootstrap ClassLoader
                try {
                    cl = ClassLoader.getSystemClassLoader();
                } catch (Throwable ex) {
                    // Cannot access system ClassLoader - oh well, maybe the caller can live with null...
                }
            }
        }
        return cl;
    }


}
